package com.kob.backend.controller.user.account;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kob.backend.mapper.DueHistoryMapper;
import com.kob.backend.mapper.SeatMapper;
import com.kob.backend.mapper.SeatRecordMapper;
import com.kob.backend.pojo.DueHistroy;
import com.kob.backend.pojo.Seat;
import com.kob.backend.pojo.SeatRecord;
import com.kob.backend.service.user.DueHistoryService;
import com.kob.backend.service.user.SeatRecordService;
import com.kob.backend.utils.DateTimeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/*
 * 获取传感器传来的数据，进行座位变化
 * 有人1，无人0
 */
@Service
@RestController
public class SeatStatusUpdateService {

    SerialCommunication port = new SerialCommunication();
    @Autowired
    DueHistoryService dueHistoryService;

    @Autowired
    DueHistoryMapper dueHistoryMapper;

    @Autowired
    SeatRecordService seatRecordService;

    @Autowired
    SeatRecordMapper seatRecordMapper;


    @Autowired
    DateTimeUtils dateTimeUtils;

    /*
    *每6秒接收一次从串口传来的数据
     */
    @Scheduled(fixedRate = 6000) // 每隔6s执行一次
    @PostMapping("user/account/portseatstatus/")
    @CrossOrigin(origins = "http://localhost:8080") // 允许跨域请求从指定源
    public int[] updateSeatStatus() {
        int[] seatports = new int[25];  // 一次接收25个传感器端口传来的数据
        // 使传感器固定检测座位10
        seatports[10] = port.getReceivedData();
//        seatports[10] =1;

//        System.out.println("seat 10 :"+seatports[10]);
        return seatports;
    }

    /*
     * 每6s，自动检测所有数据库中所有未进行签到记录
     * 如果已经过了签到时间且未取消预约的，就自动取消预约
     * 防止未签到而占用座位
     */
    @Scheduled(fixedRate = 6000)
    public void cancelPastDueReservations(){
        // 获取数据库中未签到的所有记录
        List<DueHistroy> pastDueHistory = dueHistoryService.findPastDueHistory();
        // 遍历所有记录，满足条件的取消预约
        for(DueHistroy dh : pastDueHistory){
            String dateSlot = dh.getDate();
            String timeSlot = dh.getTime();

            // 获取预约时间段开始与结束的时间
            String[] dateTime = dateTimeUtils.GetSatrtEndTime(dateSlot, timeSlot);
            String  startTime = dateTime[0];
            String  endTime = dateTime[1];
            String dueTime = dh.getDuetime();

            // 时间段开始结束时间 转为日期格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
            LocalDateTime EndDateTime = LocalDateTime.parse(endTime, formatter);
            LocalDateTime startDateTime = LocalDateTime.parse(startTime, formatter);
            // 预约时间
            DateTimeFormatter formatter_s = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime dueDateTime = LocalDateTime.parse(dueTime, formatter_s);


            // 获取签到结束的时间
            LocalDateTime signEndTime;
            // 判断预约的时间是否在时间段内
            // 将时间往后加10分钟
            if(dueDateTime.isAfter(startDateTime) && dueDateTime.isBefore(EndDateTime))
            {
                signEndTime = dueDateTime.plusMinutes(10);
            }
            else{
                signEndTime = startDateTime.plusMinutes(10);
            }

            // 获取当前时间
            LocalDateTime nowTime = LocalDateTime.now();
            // 检查 signEndTime 是否在当前时间之前 并且未取消预约
            if (signEndTime.isBefore(nowTime) && dh.getIscancel() == 0) {
                // 删除recored表中的该条记录,这样才会使签到的选座图标更新
                SeatRecord seatRecord = new SeatRecord();

                QueryWrapper<SeatRecord> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("seatId", dh.getSeatid())
                        .eq("dateSlot",dh.getDate())
                        .eq("timeSlot",dh.getTime());
                int res = seatRecordMapper.delete(queryWrapper);
                // 取消预约
                dh.setIscancel(1);
                dueHistoryMapper.updateById(dh);
                System.out.println("系统自动取消预约成功，预约记录id：" + dh.getId());
            }
        }
    }

    /*
     * 查找已签到，在使用时间段内，但长时间没人坐
     * 每隔五分钟检测一次
     * 如果检测到没有人坐，就将该座位号放入seatLeaveSet集合中
     * 如果第二次五分钟检测，还是没人，就判定当前位置真没人，就释放座位
     * 如果第二次有人了，就把这个座位号从seatLeaveSet中取出
     */
    Set<Integer> seatLeaveSet = new HashSet<>();
    // 每隔五分钟执行一次检测
    @Scheduled(fixedRate = 5 * 60 * 1000)
    public void detectSeats() {
        // 如果当前时间在这几个空闲时间段内，就设置seatLeaveSet为空
        // 获取当前时间
        LocalTime nowTime = LocalTime.now();
        if(dateTimeUtils.IsInTimeSlot(nowTime)){
            seatLeaveSet.clear();
            System.out.println("zhix");
        }
        else {

            // 获取已签到，且未取消的记录
            List<DueHistroy> signedInRecords = dueHistoryService.findSignInAndNCancelHistory();
            System.out.println("list数量" + signedInRecords.size());
            // [Debug] 测试25个座位端口传来的数据
            int[] seatports = new int[25];
            // [Debug] 将所有端口设置为1
            Arrays.fill(seatports, 1);
            // [Debug] 将端口12设置为0
//            seatports[12] = 0;
            seatports[12] = port.getReceivedData();
            System.out.println("端口数据12：" + port.getReceivedData());


            for (DueHistroy dh : signedInRecords) {
                // 判定当前时间是否在该记录的时间段内
                String dateSlot = dh.getDate();
                String timeSlot = dh.getTime();

                // 获取预约时间段开始与结束的时间
                String[] dateTime = dateTimeUtils.GetSatrtEndTime(dateSlot, timeSlot);
                String startTime = dateTime[0];
                String endTime = dateTime[1];
//            String dueTime = dh.getDuetime();

                // 时间段开始结束时间 转为日期格式
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
                LocalDateTime startDateTime = LocalDateTime.parse(startTime, formatter);
                LocalDateTime EndDateTime = LocalDateTime.parse(endTime, formatter);

                // 获取当前时间
                LocalDateTime nowDateTime = LocalDateTime.now();
                if (nowDateTime.isAfter(startDateTime) && nowDateTime.isBefore(EndDateTime)) {
                    // 当前时间在时间段内
                    // 执行检测逻辑
                    // 如果该记录无人，且seatLeaveSet不存在，就把座位号插入seatLeaveSet。
//                if(port.getReceivedData() == 0 && !seatLeaveSet.contains(dh.getSeatid())){
                    // [Debug]
                    if (seatports[dh.getSeatid()] == 0 && !seatLeaveSet.contains(dh.getSeatid())) {
                        // 将该记录的座位号加入list中。
                        seatLeaveSet.add(dh.getSeatid());
                        System.out.println("第一次检测到座位:" + dh.getSeatid() + "无人");
                    }
                    // 如果该记录无人，且seatLeaveSet存在，就把座位号取出，并取消该座位预约，并设置isout为1
//                else if(port.getReceivedData() == 0 && seatLeaveSet.contains(dh.getSeatid())){
                    // [Debug]
                    else if (seatports[dh.getSeatid()] == 0 && seatLeaveSet.contains(dh.getSeatid())) {

                        seatLeaveSet.remove(dh.getSeatid()); // 取出该座位号
                        // 取消预约
                        dh.setIscancel(1);
                        dh.setIsout(1);
                        dueHistoryMapper.updateById(dh);
                        // 删除seatRecored表中记录
                        QueryWrapper<SeatRecord> queryWrapper = new QueryWrapper<>();
                        queryWrapper.eq("seatId", dh.getSeatid())
                                .eq("dateSlot", dh.getDate())
                                .eq("timeSlot", dh.getTime());
                        int res = seatRecordMapper.delete(queryWrapper);
                        System.out.println("res:" + res + "检测到座位号：" + dh.getSeatid() + " 无人，自动释放该位置");
                    }
                    // 如果座位有人，且seatLeaveSet存在，就把座位号取出
//                else if(port.getReceivedData() == 1 && !seatLeaveSet.contains(dh.getSeatid())){
                    // [Debug]
                    else if (seatports[dh.getSeatid()] == 1 && seatLeaveSet.contains(dh.getSeatid())) {

                        seatLeaveSet.remove(dh.getSeatid());
                        System.out.println("检测到座位号：" + dh.getSeatid() + " 有人,将座位号取出");
                    }
                }
            }
        }
    }
}